package cn.px.service.store.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.px.dao.entity.store.SpareRecoveryDetail;
import com.github.pagehelper.PageHelper;
import cn.px.common.bean.AbstractPageResultBean;
import cn.px.common.model.UserInfo;
import cn.px.common.util.BeanConverterUtil;
import cn.px.common.util.IdGeneratorUtils;
import cn.px.common.util.SecurityUtils;
import cn.px.dao.bean.MyPage;
import cn.px.dao.dto.store.SpareRecoveryDetailDTO;
import cn.px.dao.dto.store.SpareRecoveryFormDTO;
import cn.px.dao.entity.sqarepartmanage.SparePartUsed;
import cn.px.dao.entity.store.SpareRecoveryForm;
import cn.px.dao.enums.SparePartUsedStatusEnum;
import cn.px.dao.mapper.sqarepartmanage.SparePartUsedMapper;
import cn.px.dao.mapper.store.SpareRecoveryDetailMapper;
import cn.px.dao.mapper.store.SpareRecoveryFormMapper;
import cn.px.dao.vo.query.store.SpareRecoveryFormVO;
import cn.px.service.base.impl.BaseServiceImpl;
import cn.px.service.store.SpareRecoveryFormService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.weekend.Weekend;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description 备件领用登记单 service 实现类
 * @author 品讯科技
 * @date 2024-08
 * @Version Copyright (c) 2020,北京乾元坤和科技有限公司 All rights reserved.
 */
@AllArgsConstructor
@Service("spareRecoveryFormService")
public class SpareRecoveryFormServiceImpl extends BaseServiceImpl<SpareRecoveryFormMapper, SpareRecoveryForm, SpareRecoveryFormDTO> implements SpareRecoveryFormService {
    private SpareRecoveryDetailMapper detailMapper;
    private SparePartUsedMapper sparePartUsedMapper;
    @Override
    public int batchDelete(List<String> ids) {
        ids.forEach(id -> {
            cascadingDeleteByKey(id);
        });
        return 1;
    }

    @Override
    public AbstractPageResultBean<SpareRecoveryFormVO> selectPageList(SpareRecoveryFormDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    @Override
    public SpareRecoveryFormVO getDetail(Object id) {
        SpareRecoveryForm SpareRecoveryForm = getModelById(id);
        SpareRecoveryFormVO SpareRecoveryFormVO = new SpareRecoveryFormVO();
        BeanConverterUtil.copyObjectProperties(SpareRecoveryForm,SpareRecoveryFormVO);
        SpareRecoveryFormVO.setDetailList(mapper.selectDetailList(id));
        return SpareRecoveryFormVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cascadingDeleteByKey(String id) {
        mapper.deleteByPrimaryKey(id);
        Weekend<SpareRecoveryDetail> detailWeekend = new Weekend<>(SpareRecoveryDetail.class);
        detailWeekend.weekendCriteria().andEqualTo(SpareRecoveryDetail::getPickId, id);
        int result = detailMapper.deleteByExample(detailWeekend);
    }

    @Override
    public void updateModelByDTO(SpareRecoveryFormDTO model) {
        // 更新
        super.modModelByDTO(model);

        // 先删除后插入
        Weekend<SpareRecoveryDetail> detailWeekend = new Weekend<>(SpareRecoveryDetail.class);
        List<SpareRecoveryDetailDTO> detailList = model.getDetailList();
        List<String> ids = detailList.stream().map(SpareRecoveryDetailDTO::getId).collect(Collectors.toList());
        detailWeekend.weekendCriteria().andNotIn(SpareRecoveryDetail::getId, ids).andEqualTo(SpareRecoveryDetail::getPickId,model.getId());

        List<SpareRecoveryDetail> delDetailList = detailMapper.selectByExample(detailWeekend);
        // 回滚使用表状态信息
        delDetailList.forEach(detail -> {
            Weekend<SparePartUsed> spareStoreWeekend = new Weekend<>(SparePartUsed.class);
            spareStoreWeekend.weekendCriteria().andEqualTo(SparePartUsed::getSpareId, detail.getSpareUsedId());
            SparePartUsed sparePartUsed = sparePartUsedMapper.selectOneByExample(spareStoreWeekend);
            if (!ObjectUtil.isNull(sparePartUsed)) {// 沒有该备件和用户所属的二级库存,则抛出异常提示要先新增该库存，新增通过备件领用，从一级库领用。有了，则更新
                sparePartUsed.setStatus(SparePartUsedStatusEnum.REPLACEMENTED.getValue());
                sparePartUsedMapper.updateByPrimaryKey(sparePartUsed);
            }
        });
        detailMapper.deleteByExample(detailWeekend);

        detailList.forEach(detail -> {
            SpareRecoveryDetail realDetail = detailMapper.selectByPrimaryKey(detail.getId());
            if(ObjectUtil.isNull(realDetail)) {// 新增的
                detail.setUserInfo();
                detail.setPickId(model.getId());
                detail.setPickNo(model.getPickNo());
                SpareRecoveryDetail storeDetail = new SpareRecoveryDetail();
                BeanConverterUtil.copyObjectProperties(detail, storeDetail);
                SpareRecoveryDetail result = detailMapper.selectByPrimaryKey(detail.getId());
                storeDetail.setId(IdGeneratorUtils.getObjectId());
                detailMapper.insertSelective(storeDetail);

                // 更新使用表的备件状态为已回收
                Weekend<SparePartUsed> spareStoreWeekend = new Weekend<>(SparePartUsed.class);
                spareStoreWeekend.weekendCriteria().andEqualTo(SparePartUsed::getId, storeDetail.getSpareUsedId());
                SparePartUsed sparePartUsed = sparePartUsedMapper.selectOneByExample(spareStoreWeekend);
                if (!ObjectUtil.isNull(sparePartUsed)) {
                    sparePartUsed.setStatus(SparePartUsedStatusEnum.RECOVERY.getValue());
                    sparePartUsedMapper.updateByPrimaryKey(sparePartUsed);
                }
            }
        });
    }

    @Override
    public AbstractPageResultBean<SpareRecoveryForm> selectPageInfo(SpareRecoveryFormDTO record, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        return new MyPage(mapper.selectList(record));
    }

    @Override
    public SpareRecoveryForm saveModelByDTO(SpareRecoveryFormDTO model) {
        Weekend<SpareRecoveryForm> weekend = new Weekend<>(SpareRecoveryForm.class);
        weekend.weekendCriteria().andIsNotNull(SpareRecoveryForm::getId);
        Integer count = mapper.selectCountByExample(weekend);
        model.setPickNo(IdGeneratorUtils.getSpareRecoveryNo(++count));
        SpareRecoveryForm SpareRecoveryForm = super.saveModelByDTO(model);
        // 领用详情
        UserInfo userInfo = SecurityUtils.getUserInfo();
        List<SpareRecoveryDetailDTO> detailList = model.getDetailList();
        // 先删除后插入
        Weekend<SpareRecoveryDetail> detailWeekend = new Weekend<>(SpareRecoveryDetail.class);
        List<String> ids = detailList.stream().map(SpareRecoveryDetailDTO::getId).collect(Collectors.toList());
        detailWeekend.weekendCriteria().andNotIn(SpareRecoveryDetail::getId, ids).andEqualTo(SpareRecoveryDetail::getPickId,SpareRecoveryForm.getId());
        detailMapper.deleteByExample(detailWeekend);
        detailList.forEach(detail -> {
            detail.setUserInfo(userInfo);
            detail.setPickId(SpareRecoveryForm.getId());
            detail.setPickNo(SpareRecoveryForm.getPickNo());
            SpareRecoveryDetail storeDetail = new SpareRecoveryDetail();
            BeanConverterUtil.copyObjectProperties(detail, storeDetail);
            SpareRecoveryDetail result = detailMapper.selectByPrimaryKey(detail.getId());
            if (ObjectUtil.isNull(result)) {
                detail.setId(IdGeneratorUtils.getObjectId());
                detailMapper.insertSelective(storeDetail);
            } else {
                storeDetail.setUpdateTime(LocalDateTime.now());
                storeDetail.setUpdateUserId(userInfo.getUserId());
                detailMapper.updateByPrimaryKeySelective(storeDetail);
            }

            // 更新使用表状态为已回收
            SparePartUsed updateSparePartUsed = new SparePartUsed();
            updateSparePartUsed.setId(storeDetail.getSpareUsedId());
            updateSparePartUsed.setStatus(SparePartUsedStatusEnum.RECOVERY.getValue());
            sparePartUsedMapper.updateByPrimaryKeySelective(updateSparePartUsed);
        });
        return SpareRecoveryForm;
    }
}
